using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;

namespace vXCopy
{
	class FileToProcessList
	{
		private List<FileToProcess> _filesList = null;

		public List<FileToProcess> FilesList
		{
			get { return _filesList; }
			set { _filesList = value; }
		}

		public FileToProcessList()
		{
			_filesList = new List<FileToProcess>();
		}

	}

	class FileToProcess : System.EventArgs
	{

		private FileInfo _oFileSourceInfo = null;
		private FileInfo _oFileDestInfo = null;

		private DirectoryInfo _ofromFolder;
		private DirectoryInfo _oDestFolder;

		private Int32 _rowid = 0;

		private string _fromFolder = "";
		private string _destFolder = "";
		private string _fromFile = "";
		private string _destFile = "";
		private int _maxthreads = 4;
		private int _threadcount = 0;

		private DateTime _startCopyDateTime = new DateTime(1980, 2, 1, 23, 59, 59);
		private long _bytesCopied = 0;

		private string _includeFiles = "";
		private string _includeFolders = "";
		private string _excludeFiles = "";
		private string _excludeFolders = "";

		private bool _forceCopy = false;
		private bool _purgeCopy = false;

		private decimal _processStatus = 0;
		private int _threadID = 0;
		private int _itemNumber = 0;
		private string _itemStatus = "";
		private string _errorStatus = "";
		private string _errorStack = "";

		private int _totalFiles = 0;

		public bool CheckToProcess()
		{
			//FileInfo ofileFromInfo = null;
			//FileInfo ofileDestInfo = null;

			try
			{

				///////////////////////////////////////////////////////
				// Check Include Exclude files
				///////////////////////////////////////////////////////
				bool bMatchFile = true;
				bool bMatchFolder = true; ;
				bool bNoMatchFile = false; ;
				bool bNoMatchFolder = false; ;

				string regIncludeFiles = UtilLibrary.CreateRegExFromString(this.IncludeFiles);
				string regExcludeFiles = UtilLibrary.CreateRegExFromString(this.ExcludeFiles);
				string regIncludeFolders = UtilLibrary.CreateRegExFromString(this.IncludeFolders);
				string regExcludeFolders = UtilLibrary.CreateRegExFromString(this.ExcludeFolders);

				if (regIncludeFiles.Length != 0)
				{
					Match matchFile = Regex.Match(this.oFileSourceInfo.Name, regIncludeFiles, RegexOptions.IgnoreCase);
					bMatchFile = matchFile.Success;
				}

				if (regIncludeFolders.Length != 0)
				{
					Match matchFolder = Regex.Match(this.ofromFolder.Name, regIncludeFolders, RegexOptions.IgnoreCase);
					bMatchFolder = matchFolder.Success;
				}

				//Check if we must quit now or continue checking folders+files
				if (!(bMatchFile && bMatchFolder))
					return false;

				if (regExcludeFiles.Length != 0)
				{
					Match nomatchFile = Regex.Match(this.oFileSourceInfo.Name, regExcludeFiles, RegexOptions.IgnoreCase);
					bNoMatchFile = nomatchFile.Success;
				}
				if (regExcludeFolders.Length != 0)
				{
					Match nomatchFolder = Regex.Match(this.ofromFolder.Name, regExcludeFolders, RegexOptions.IgnoreCase);
					bNoMatchFolder = nomatchFolder.Success;
				}

				//Check if we must quit now or continue checking folders+files
				if (bNoMatchFile || bNoMatchFolder)
					return false;

				///////////////////////////////////////////////////////
				// Check Files's status
				///////////////////////////////////////////////////////

				if (this.fromFile.Length == 0 || this.destFile.Length == 0)
					return true;

				//Check if we need to bypass any check
				if (ForceCopy)
					return true;

				//ofileFromInfo = new FileInfo(this.fromFile);
				//ofileDestInfo = new FileInfo(this.destFile);
				if (oFileDestInfo.Exists)
				{
					TimeSpan oFromFileDataTime = new TimeSpan(oFileSourceInfo.LastWriteTimeUtc.Ticks);
					TimeSpan oDestFileDataTime = new TimeSpan(oFileDestInfo.LastWriteTimeUtc.Ticks);

					if (oDestFileDataTime == oFromFileDataTime)
					{
						//Debug.WriteLine("%%ofileFromInfo-ofileDestInfo: " + oFileSourceInfo.FullName + " -- " + oFileSourceInfo.LastWriteTimeUtc.ToString() + " -- " + oFileSourceInfo.Length);
						//Debug.WriteLine("%%ofileFromInfo-ofileDestInfo: " + oFileDestInfo.FullName + " -- " + oFileSourceInfo.LastWriteTimeUtc.ToString() + " -- " + oFileSourceInfo.Length);

						if (oFileSourceInfo.Length == oFileDestInfo.Length)
						{
							return false;
						}
					}
				}

				//ofileFromInfo = null;
				//ofileDestInfo = null;
				
				return true;
			}
			catch (Exception ex)
			{
				Debug.WriteLine("FileToProcess::CheckToProcess:Error: " + ex.Message);
				return true;
			}
		}

		public Int32 RowID
		{
			get { return _rowid; }
			set
			{
				lock (this)
				{
					_rowid = value;
				}
			}
		}

		public FileInfo oFileSourceInfo
		{
			get
			{
				if (_oFileSourceInfo == null)
					_oFileSourceInfo = new FileInfo(this.fromFile);
				_oFileSourceInfo.Refresh();
				return _oFileSourceInfo;
			}
			set
			{
				lock (this)
				{
					_oFileSourceInfo = value;
				}
			}
		}

		public FileInfo oFileDestInfo
		{
			get
			{
				if (_oFileDestInfo == null)
					_oFileDestInfo = new FileInfo(this.destFile);
				_oFileDestInfo.Refresh();
				return _oFileDestInfo;
			}
			set
			{
				lock (this)
				{
					_oFileDestInfo = value;
				}
			}
		}

		public DirectoryInfo ofromFolder
		{
			get
			{
				if (_ofromFolder == null)
					_ofromFolder = new DirectoryInfo(this.fromFolder);
				_ofromFolder.Refresh();
				return _ofromFolder;
			}
			set
			{
				lock (this)
				{
					_ofromFolder = value;
				}
			}
		}

		public DirectoryInfo oDestFolder
		{
			get
			{
				if (_oDestFolder == null)
					_oDestFolder = new DirectoryInfo(this.destFolder);
				_oDestFolder.Refresh();
				return _oDestFolder;
			}
			set
			{
				lock (this)
				{
					_oDestFolder = value;
				}
			}
		}

		public string fromFolder
		{
			get { return _fromFolder; }
			set
			{
				lock (this)
				{
					_fromFolder = value;
				}
			}
		}

		public string destFolder
		{
			get { return _destFolder; }
			set
			{
				lock (this)
				{ _destFolder = value; }
			}
		}

		public string fromFile
		{
			get { return _fromFile; }
			set
			{
				lock (this)
				{
					_fromFile = value;
				}

			}
		}

		public string destFile
		{
			get { return _destFile; }
			set
			{
				lock (this)
				{
					_destFile = value;
				}
			}
		}


		public string IncludeFolders
		{
			get { return _includeFolders; }
			set
			{
				lock (this)
				{
					_includeFolders = value;
				}
			}
		}

		public string IncludeFiles
		{
			get { return _includeFiles; }
			set
			{
				lock (this)
				{
					_includeFiles = value;
				}
			}
		}

		public string ExcludeFolders
		{
			get { return _excludeFolders; }
			set
			{
				lock (this)
				{
					_excludeFolders = value;
				}
			}
		}

		public string ExcludeFiles
		{
			get { return _excludeFiles; }
			set
			{
				lock (this)
				{
					_excludeFiles = value;
				}
			}
		}
		public int MaxThreads
		{
			get { return _maxthreads; }
			set
			{
				lock (this)
				{
					_maxthreads = value;
				}
			}
		}

		public int ThreadCount
		{
			get { return _threadcount; }
			set
			{
				lock (this)
				{
					_threadcount = value;
				}
			}
		}

		public decimal ProcessStatus
		{
			get { return _processStatus; }
			set
			{
				lock (this)
				{
					_processStatus = value;
				}
			}
		}

		public int ThreadID
		{
			get { return _threadID; }
			set
			{
				lock (this)
				{
					_threadID = value;
				}
			}
		}

		public int ItemNumber
		{
			get { return _itemNumber; }
			set
			{
				lock (this)
				{
					_itemNumber = value;
				}

			}
		}

		public int TotalFiles
		{
			get { return _totalFiles; }
			set
			{
				lock (this)
				{
					_totalFiles = value;
				}

			}
		}

		public long BytesCopied
		{
			get { return _bytesCopied; }
			set
			{
				lock (this)
				{
					_bytesCopied = value;
				}

			}
		}

		public DateTime StartCopyDateTime
		{
			get { return _startCopyDateTime; }
			set
			{
				lock (this)
				{
					_startCopyDateTime = value;
				}

			}
		}

		public string ItemStatus
		{
			get { return _itemStatus; }
			set
			{
				lock (this)
				{
					_itemStatus = value;
				}
			}
		}

		public string ErrorStatus
		{
			get
			{
				return _errorStatus;
			}
			set
			{
				lock (this)
				{
					_errorStatus = value;
				}
			}
		}


		public string ErrorStack
		{
			get
			{
				return _errorStack;
			}
			set
			{
				lock (this)
				{
					_errorStack = value;
				}
			}
		}

		public bool ForceCopy
		{
			get
			{
				return _forceCopy;
			}
			set
			{
				lock (this)
				{
					_forceCopy = value;
				}
			}
		}

		public bool PurgeCopy
		{
			get
			{
				return _purgeCopy;
			}
			set
			{
				lock (this)
				{
					_purgeCopy = value;
				}
			}
		}

	}


}
